package services_tenant

import (
	"esc.show/multiple_database/internal/core"
	"esc.show/multiple_database/internal/core/databases"
	"esc.show/multiple_database/tenants/model"
	"fmt"
	"github.com/spf13/viper"
)

// RegisterTenantDB 注册租户数据库
func RegisterTenantDB(c *core.Core, conn string) *core.Core {

	c.TenantDb = databases.RegisterDb(c.TenantDb, conn)

	return c
}

// BuildMysqlConnByDomain 根据域名生成数据库链接
func BuildMysqlConnByDomain(c *core.Core, domain string) (string, error) {

	var domainData model.Domain

	err := c.Db.Where("domain=?", domain).First(&domainData).Error

	if err != nil {
		return "", err
	}

	var tenant model.Tenant

	err = c.Db.Where("id=?", domainData.TenantId).First(&tenant).Error

	if err != nil {
		return "", err
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		viper.GetString("database.username"),
		viper.GetString("database.password"),
		viper.GetString("database.host"),
		viper.GetString("database.port"),
		tenant.Data["tenancy_db_name"].(string),
	)

	return dsn, nil
}

func BuildMysqlConnByTenantId(c *core.Core, tenantId string) (dsn string, err error) {
	var tenant model.Tenant

	err = c.Db.Where("id=?", tenantId).First(&tenant).Error

	if err != nil {
		return "", err
	}
	dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		viper.GetString("database.username"),
		viper.GetString("database.password"),
		viper.GetString("database.host"),
		viper.GetString("database.port"),
		tenant.Data["tenancy_db_name"].(string),
	)
	return dsn, nil

}

// Tenant 获取租户信息
func Tenant(c *core.Core) (tenant *model.Tenant) {

	domain := c.GinContext.Request.Host

	var domainTenant model.Domain

	err := c.Db.Where("domain=?", domain).First(&domainTenant).Error

	if err != nil {
		return nil
	}

	err = c.Db.Where("id=?", domainTenant.TenantId).First(&tenant).Error

	if err != nil {
		return nil
	}
	return tenant

}

// Init 初始化租户信息
func Init(c *core.Core, TenantId string) *core.Core {

	if c.TenantID != TenantId {
		if TenantId != "" {
			dsn, err := BuildMysqlConnByTenantId(c, TenantId)
			if err != nil {
				c.TenantDb = nil
				return c
			}
			c = RegisterTenantDB(c, dsn)
		} else {
			c.TenantDb = nil
		}
	}
	return c
}
